package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.DTO.EmpDTO;
import com.itheima.mapper.DeptMapper;
import com.itheima.mapper.EmpExprMapper;
import com.itheima.mapper.EmpLogMapper;
import com.itheima.pojo.*;
import com.itheima.service.DeptService;
import com.itheima.service.EmpExprService;
import com.itheima.service.EmpLogService;
import com.itheima.service.EmpService;
import com.itheima.mapper.EmpMapper;
import com.itheima.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {


    @Autowired
    private DeptService deptService;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private EmpExprService empExprService;

    @Autowired
    private EmpExprMapper empExprMapper;
    @Autowired
    private EmpLogService empLogService;

    @Override
    public PageResult pageQuery(EmpQueryParam empPageQuery) {
        Integer page = empPageQuery.getPage(); // 当前页码
        Integer pageSize = empPageQuery.getPageSize(); // 每页条数

        // 1. 创建分页对象
        Page<Emp> p = new Page<>(page, pageSize);

        // 2. 构建查询条件

        QueryWrapper<Emp> wrapper = new QueryWrapper<>();

        if (empPageQuery.getName() != null) {
            wrapper.like("e.name", empPageQuery.getName()); // 使用别名e来明确指定表名
        }
        if (empPageQuery.getGender() != null) {
            wrapper.eq("e.gender", empPageQuery.getGender()); // 使用别名e来明确指定表名
        }
        if (empPageQuery.getBegin() != null && empPageQuery.getEnd() != null) {
            wrapper.between("e.entry_date", empPageQuery.getBegin(), empPageQuery.getEnd()); // 使用别名e来明确指定表名
        }
        // 3. 添加排序条件，根据updateTime倒序排序
        wrapper.orderByDesc("e.update_time");


        // 3. 调用自定义的分页查询方法
        //通用mapper
        empMapper.list2(p, wrapper);

        // 4. 返回分页结果
        return new PageResult(p.getTotal(), p.getRecords());
    }

    //该接口用于添加员工的信息包括员工经历信息
//    @Override
//    public void mySave(Emp emp) {
//        emp.setCreateTime(LocalDateTime.now());
//        emp.setUpdateTime(LocalDateTime.now());
//        //保存员工基本信息
//       empMapper.mySave(emp);
//        //保存员工经历信息
//        Integer empId = emp.getId();
//        List<EmpExpr> exprList = emp.getExprList();
//        if (!CollectionUtils.isEmpty(exprList)) {
//            exprList.forEach(empExpr -> empExpr.setEmpId(empId));
//            //保存员工经历信息
//          empExprMapper.insertBatch(exprList);
//        }
//
//    }
    //该接口用于添加员工的信息包括员工经历信息
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void mySave(Emp emp) {
        try {
            // 设置创建时间和更新时间
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());

            // 保存员工基本信息
            empMapper.mySave(emp);
            // 保存员工经历信息
            Integer empId = emp.getId(); // 获取保存员工基本信息后的员工ID
            List<EmpExpr> exprList = emp.getExprList();
            //如果员工没有添加员工经历信息，则直接返回
            if (!CollectionUtils.isEmpty(exprList)) {
                // 设置每条经历的 empId
                exprList.forEach(empExpr -> empExpr.setEmpId(empId));

                // 批量保存员工经历信息
                empExprService.saveBatch(exprList);
            }

        } finally {
            //记录员工操作日志
            EmpLog empLog = new EmpLog(null, LocalDateTime.now(), emp.toString());
            empLogService.insertLog(empLog);
        }

    }

    /**
     * 批量删除员工
     */
//    在删除员工信息时，
//    既需要删除 emp 表中的员工基本信息，
//    还需要删除 emp_expr 表中员工的工作经历信息
    @Transactional
    @Override
    public void deleteByIds(List<Integer> ids) {
        //1. 根据ID批量删除员工基本信息
        empMapper.deleteBatchIds(ids);

        //2. 根据员工的ID批量删除员工的工作经历信息
//        方法1
//        empExprMapper.deleteByEmpIds(ids);

//        方法2
        LambdaQueryWrapper<EmpExpr> wrapper = new LambdaQueryWrapper<>();
        empExprMapper.delete(wrapper.in(EmpExpr::getEmpId, ids));
    }

    //    该接口用于查询全部员工信息
    @Override
    public List<EmpDTO> findEmpList() {
        List<EmpDTO> empList = empMapper.list();
        return empList;

    }

    /**
     * 登录
     */
    @Override
    public LoginInfo login(Emp emp) {
        QueryWrapper<Emp> wrapper = new QueryWrapper<>();
        wrapper.eq("username", emp.getUsername())
                .eq("password", emp.getPassword())
                .select("id", "username", "name");
        Emp empLogin = empMapper.selectOne(wrapper);
        //判断是否有这个员工，如果有返回员工登录信息，如果没有返回null
        if (empLogin != null) {
            log.info("员工登录成功,员工的信息是{}", empLogin);
            //生成jwt令牌
            HashMap<String, Object> claims = new HashMap<>();
            claims.put("id", empLogin.getId());
            claims.put("username", empLogin.getUsername());
            String jwt = JwtUtils.generateJwt(claims);
            return new LoginInfo(empLogin.getId(), empLogin.getUsername(), empLogin.getName(), jwt);
        }
        return null;
    }


    //    > 该接口用于根据主键ID查询员工的信息
    @Override
    public Emp getInfo(Integer id) {
        return empMapper.getInfo(id);


    }

    //    该接口用于修改员工的数据信息
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(Emp emp) {
        //1. 设置更新时间
        emp.setUpdateTime(LocalDateTime.now());
        //2. 更新员工基本信息（动态更新）
//        方法1
//        empMapper.myUpdateById(emp);

        lambdaUpdate().eq(Emp::getId, emp.getId())
                .set(emp.getUsername() != null, Emp::getUsername, emp.getUsername())
                .set(emp.getPassword() != null, Emp::getPassword, emp.getPassword())
                .set(emp.getName() != null, Emp::getName, emp.getName())
                .set(emp.getGender() != null, Emp::getGender, emp.getGender())
                .set(emp.getPhone() != null, Emp::getPhone, emp.getPhone())
                .set(emp.getJob() != null, Emp::getJob, emp.getJob())
                .set(emp.getSalary() != null, Emp::getSalary, emp.getSalary())
                .set(emp.getImage() != null, Emp::getImage, emp.getImage())
                .set(emp.getEntryDate() != null, Emp::getEntryDate, emp.getEntryDate())
                .set(emp.getDeptId() != null, Emp::getDeptId, emp.getDeptId())
                .set(emp.getUpdateTime() != null, Emp::getUpdateTime, emp.getUpdateTime())
                .update();


        //3. 更新员工经历信息
        // 3.1先删除员工经历信息
        empExprMapper.deleteByEmpIds(Arrays.asList(emp.getId()));
        List<EmpExpr> exprList = emp.getExprList();
        // 如果员工没有经历信息，就是说明删除员工经历信息后没有添加新的员工经历信息，则直接返回
        //添加了就保存
        if (!CollectionUtils.isEmpty(exprList)) {
            // 3.2再添加保存员工经历信息
            exprList.forEach(empExpr -> empExpr.setEmpId(emp.getId()));
            empExprMapper.insertBatch(exprList);//批量保存员工经历信息

        }


    }


}